package qx.hyj.petrescue.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import qx.hyj.petrescue.entity.BaseEntity;
import qx.hyj.petrescue.param.ConditionParam;
import qx.hyj.petrescue.service.IBaseService;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Slf4j
@Service
public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntity<K>, K extends Serializable> extends ServiceImpl<M, T> implements IBaseService<T, K> {

    protected static final Logger LOGGER = LoggerFactory.getLogger(BaseServiceImpl.class);


    /**
     * 获取 T 的class
     *
     * @return Class<T>
     */
    public abstract Class<T> getBaseClazz();

    @Override
    public boolean save(T entity) {
        updateBefore(entity, true);
        return super.save(entity);
    }

    @Override
    public boolean updateById(T entity) {
        updateBefore(entity, false);
        return super.updateById(entity);
    }

    @Override
    public List<T> list(Wrapper<T> queryWrapper) {
        boolean notSupport = queryWrapper == null || "EmptyWrapper".equals(queryWrapper.getClass().getSimpleName());
        if (!notSupport && Arrays.stream(getBaseClazz().getDeclaredFields()).anyMatch(e -> "xgsj".equals(e.getName()))) {
            if (queryWrapper instanceof LambdaQueryWrapper) {
                LambdaQueryWrapper<T> lambdaQueryWrapper = (LambdaQueryWrapper<T>) queryWrapper;
                //lambdaQueryWrapper.apply(" order by xgsj desc");
            } else if (queryWrapper instanceof QueryWrapper) {
                QueryWrapper<T> myQueryWrapper = (QueryWrapper<T>) queryWrapper;
                myQueryWrapper.orderByDesc("xgsj");
            }
        }
        return super.list(queryWrapper);
    }

    public List<T> list(ConditionParam<T> conditionParam, HttpServletRequest request) {
        T condition = conditionParam.getCondition();
        QueryWrapper<T> queryWrapper = new QueryWrapper<>(condition);
        T filter = conditionParam.getFilter();
        if (filter != null) {
            Map<String, Object> beanToMap = BeanUtil.beanToMap(filter, false, true);
            for (Map.Entry<String, Object> entry : beanToMap.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                queryWrapper.like(key, value);
            }
        }
        Class<?> aClass = getEntityClass();
        String asc = conditionParam.getAsc();
        String desc = conditionParam.getDesc();
        if (aClass != null) {
            Field[] declaredFields = aClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                String name = declaredField.getName();
                if (StringUtils.isBlank(name)) {
                    continue;
                }
                if (name.equals(asc)) {
                    queryWrapper.orderByAsc(asc);
                    continue;
                }
                if (name.equals(desc)) {
                    queryWrapper.orderByDesc(desc);
                }
            }
        }
        boolean xgsjOrderDesc = false;
        if (aClass != null) {
            Field[] declaredFields = aClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                String name = declaredField.getName();
                if ("xgsj".equals(name)) {
                    xgsjOrderDesc = true;
                    break;
                }
            }
        }
        queryWrapper.orderByDesc(xgsjOrderDesc, "xgsj");
        List<T> list = null;
        try {
            list = list(queryWrapper);
        } catch (Exception e) {
            log.error("查询出错", e);
        }
        //List<T> records = page1.getRecords();
        //PageModel<List<T>> listPageModel = new PageModel<>(page1.getTotal(), records);
        //LogUtil.op(request, "分页查询" + getEntityName() + "", "分页查询" + getEntityName() + "");
        return list;
    }

    @Override
    public void updateBefore(T entity, boolean isNew) {
    }

//    @Override
//    public void excludeColumn(Wrapper<T> tWrapper, String... excludeColumns) {
//        if (excludeColumns == null || excludeColumns.length == 0) {
//            return;
//        }
//        List<String> excludeList = Arrays.asList(excludeColumns);
//        Field[] declaredFields = getBaseClazz().getDeclaredFields();
//        List<Field> fields = Arrays.asList(declaredFields);
//        List<String> fieldNames = fields.stream().map(Field::getName).collect(Collectors.toList());
//        List<String> leftFields = fieldNames.stream().filter(e -> !excludeList.contains(e)).collect(Collectors.toList());
//        String[] columns = leftFields.toArray(new String[]{});
//        if (tWrapper instanceof QueryWrapper) {
//            ((QueryWrapper<T>) tWrapper).select(columns);
//        }
//        if (tWrapper instanceof LambdaQueryWrapper) {
//            Predicate<TableFieldInfo> predicate = e -> {
//                String column = e.getColumn();
//                return leftFields.contains(column);
//            };
//            ((LambdaQueryWrapper<T>) tWrapper).select(getBaseClazz(), predicate);
//        }
//    }


}
